﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GsOrganization.Common.Helper
{
    public static class WorkerHelper
    {
        /// <summary>
        /// 运行一个后台工作线程
        /// </summary>
        /// <param name="doWork"></param>
        /// <param name="threadName"></param>
        /// <param name="progressChanged"></param>
        /// <param name="runWorkerCompleted"></param>
        /// <returns></returns>
        public static BackgroundWorker RunWorker(DoWorkEventHandler doWork, string threadName = null, ProgressChangedEventHandler progressChanged = null, RunWorkerCompletedEventHandler runWorkerCompleted = null)
        {
            BackgroundWorker backgroundWorker = new BackgroundWorker() { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
            backgroundWorker.DoWork += (sender, e) =>
            {
                LogHelper.Debug($"进程[{threadName}]:{Environment.CurrentManagedThreadId}");
                doWork.Invoke(sender, e);
            };
            if (progressChanged != null)
                backgroundWorker.ProgressChanged += progressChanged;
            if (runWorkerCompleted != null)
                backgroundWorker.RunWorkerCompleted += runWorkerCompleted;
            backgroundWorker.RunWorkerCompleted += (sender, e) =>
            {
                if ((BackgroundWorker)sender != null)
                    ((BackgroundWorker)sender).Dispose();
            };
            backgroundWorker.RunWorkerAsync();
            return backgroundWorker;
        }

        /// <summary>
        /// 运行一个后台工作线程，并传递参数
        /// </summary>
        /// <param name="args"></param>
        /// <param name="doWork"></param>
        /// <param name="threadName"></param>
        /// <param name="progressChanged"></param>
        /// <param name="runWorkerCompleted"></param>
        /// <returns></returns>
        public static BackgroundWorker RunWorker(object args, DoWorkEventHandler doWork, string threadName = null, ProgressChangedEventHandler progressChanged = null, RunWorkerCompletedEventHandler runWorkerCompleted = null)
        {
            BackgroundWorker backgroundWorker = new BackgroundWorker() { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
            backgroundWorker.DoWork += (sender, e) =>
            {
                LogHelper.Debug($"进程[{threadName}]:{Environment.CurrentManagedThreadId}");
                doWork.Invoke(sender, e);
            };
            if (progressChanged != null)
                backgroundWorker.ProgressChanged += progressChanged;
            if (runWorkerCompleted != null)
                backgroundWorker.RunWorkerCompleted += runWorkerCompleted;
            backgroundWorker.RunWorkerCompleted += (sender, e) =>
            {
                if ((BackgroundWorker)sender != null)
                    ((BackgroundWorker)sender).Dispose();
            };
            backgroundWorker.RunWorkerAsync(args);
            return backgroundWorker;
        }

        /// <summary>
        /// 运行一个后台工作线程，延时指定秒数后执行
        /// </summary>
        /// <param name="second"></param>
        /// <param name="doWork"></param>
        /// <param name="threadName"></param>
        /// <param name="progressChanged"></param>
        /// <param name="runWorkerCompleted"></param>
        /// <returns></returns>
        public static BackgroundWorker RunWorkerAfter(double second, DoWorkEventHandler doWork, string threadName = null, ProgressChangedEventHandler progressChanged = null, RunWorkerCompletedEventHandler runWorkerCompleted = null)
        {
            BackgroundWorker backgroundWorker = new BackgroundWorker() { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
            backgroundWorker.DoWork += (sender, e) =>
            {
                double secondTime = (double)e.Argument;
                Thread.Sleep(TimeSpan.FromSeconds(secondTime));
                LogHelper.Debug($"进程-{threadName}:{Environment.CurrentManagedThreadId}");
                doWork.Invoke(sender, e);
            };
            if (progressChanged != null)
                backgroundWorker.ProgressChanged += progressChanged;
            if (runWorkerCompleted != null)
                backgroundWorker.RunWorkerCompleted += runWorkerCompleted;
            backgroundWorker.RunWorkerCompleted += (sender, e) =>
            {
                if ((BackgroundWorker)sender != null)
                    ((BackgroundWorker)sender).Dispose();
            };
            backgroundWorker.RunWorkerAsync(second);
            return backgroundWorker;
        }


        /// <summary>
        /// 延时执行BackgroundWorker
        /// </summary>
        /// <param name="second">延时时间,单位(秒)</param>
        /// <param name="args">参数 object[]</param>
        /// <param name="doWork">DoWorkEventHandler</param>
        /// <param name="progressChanged">ProgressChangedEventHandler</param>
        /// <param name="runWorkerCompleted">RunWorkerCompletedEventHandler</param>
        /// <returns>BackgroundWorker</returns>
        public static BackgroundWorker RunWorkerAfter(double second, object args, DoWorkEventHandler doWork, string threadName = null, ProgressChangedEventHandler progressChanged = null, RunWorkerCompletedEventHandler runWorkerCompleted = null)
        {
            BackgroundWorker backgroundWorker = new BackgroundWorker() { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
            backgroundWorker.DoWork += (sender, e) =>
            {
                double secondTime = (double)((object[])e.Argument)[1];
                Thread.Sleep(TimeSpan.FromSeconds(secondTime));
                LogHelper.Debug($"进程-{threadName}:{Environment.CurrentManagedThreadId}");
                doWork.Invoke(sender, e);
            };
            if (progressChanged != null)
                backgroundWorker.ProgressChanged += progressChanged;
            if (runWorkerCompleted != null)
                backgroundWorker.RunWorkerCompleted += runWorkerCompleted;
            backgroundWorker.RunWorkerCompleted += (sender, e) =>
            {
                if ((BackgroundWorker)sender != null)
                    ((BackgroundWorker)sender).Dispose();
            };
            backgroundWorker.RunWorkerAsync(new object[] { args, second });
            return backgroundWorker;
        }

    }
}
